# 引入必要的库
import joblib
import yaml  # 用于读取和解析YAML文件的库。
import numpy as np
import os
import time
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
from tensorflow.keras.preprocessing import image
# 获取 0_setting.yaml 中的键 key 对应的值 value
def get(key):
    with open('0_setting.yaml', 'r',encoding='utf-8') as file:
        settings = yaml.safe_load(file)
        value = settings.get(key)
    return value

# 加载预训练的VGG16模型，不包括顶部的全连接层
model =  VGG16(weights='imagenet', include_top=False, pooling='max')

# 预处理图像, 把图像设置为指定大小之后，使用VGG16提取特征返回
def preprocess_image(file_name, new_size):
    # 1. 读取图像
    #img = Image.open(file_name)
    # 2. 调整图像大小为 new_size
    #img = img.resize(new_size)
    # 1. 使用keras内置的读图程序，以224x224的尺寸读取图像文件，结果为一个PIL图像对象
    img = image.load_img(file_name, target_size=(224, 224)) 

    # 3. 将图像转换为numpy数组，并进行预处理
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0)  # 增加一个维度，因为模型需要批量维度
    img = preprocess_input(img)
    # 4. 使用VGG16提取特征
    features = model.predict(img)
    #     print("读图的结构: ", img.shape,"如果展平后的结构: ", img.ravel().shape) 
    print("从图像中提取的特征的结构: ",features.shape)
    return features

# 用joblib把叫做 name 的对象 obj 保存(序列化)到位置 loc
def dump(obj, name, loc):
    start = time.time()
    print(f"把{name}保存到{loc}") 
    joblib.dump(obj, loc)
    end = time.time()
    print(f"保存完毕,文件位置:{loc}, 大小:{os.path.getsize(loc) / 1024 / 1024:.3f}M")
    print(f"运行时间:{end - start:.3f}秒")

# 用joblib读取(反序列化)位置loc的对象obj,对象名为name
def load(name, loc):
    print(f"从{loc}提取文件{name}")
    obj = joblib.load(f"{loc}")
    return obj